package com.bysj.lms.Shiro;

import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.bysj.lms.common.Const;
import com.bysj.lms.pojo.entity.Permission;
import com.bysj.lms.pojo.entity.Role;
import com.bysj.lms.pojo.entity.User;
import com.bysj.lms.service.IPermissionService;
import com.bysj.lms.service.IRoleService;
import com.bysj.lms.service.IUserService;
import com.bysj.lms.utils.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class JwtRealm extends AuthorizingRealm {

    private final Logger logger = LoggerFactory.getLogger(JwtRealm.class);

    @Autowired
    IUserService userService;
    @Autowired
    IRoleService roleService;

    @Autowired
    IPermissionService permissionService;


    //支持JwtToken认证
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        System.out.println("-------------------------------------------");
        //获取当前登录用户的账号
        String account = JwtUtil.getAccount((String) principal.getPrimaryPrincipal());

        logger.info("=====2当前用户："+account);
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        if(StringUtils.isNotBlank(account) && StringUtils.isNotEmpty(account)){
            //查询该用户的所有角色和权限
            //查找角色
            List<Role> roles = roleService.getByUsername(account);
            roles.forEach(role -> {if(role != null) info.addRole(String.valueOf(role.getId()));});
            logger.info("======2角色："+roles.toString());
            List<Permission> permissions = permissionService.getByRoleId(roles);
            logger.info("======2权限："+permissions.toString());
            permissions.forEach(permission -> {if(permission!=null) info.addStringPermission(permission.getUrl());});
        }
        return info;
    }

    /**
     * @Function 用来进行身份认证，验证jwtToken携带的信息是否正确
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String token = (String) authenticationToken.getCredentials();

        if(StringUtils.isBlank(token)){
            logger.info("token为空,身份认证失败!");
            throw new AuthenticationException("token为空!");
        }

        //获取token携带的用户名
        String username = JwtUtil.getAccount(token);
        //账号为空
        if(StringUtils.isBlank(username)){
            throw new AuthenticationException("token中用户为空");
        }

        User user = userService.getByUsername(username);
        if(user == null){
            throw new AuthenticationException("该账号不存在");
        }
        //开始认证
        try{
            JwtUtil.verify(token,username);
        }catch (SignatureVerificationException exception) {
            throw new SignatureVerificationException(Algorithm.HMAC256(Const.TOKEN_SECRET));
        }catch (TokenExpiredException e){
            throw new TokenExpiredException("token 过期了");
        }



        return new SimpleAuthenticationInfo(token,token,getName());
    }
}
